﻿using System;
using System.IO;
using System.Net;
using System.Windows.Forms;
using System.Web;
using System.Configuration;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Windows.Forms.VisualStyles;
using System.Diagnostics;
using static System.Net.Mime.MediaTypeNames;
using Application = System.Windows.Forms.Application;

namespace txt_file_reader
{
    public partial class FrmMain : Form
    {
        string[] _lines;
        private MP3Player _player;
        private string _path = "./temp.mp3";
        private string _next_path = "./next.mp3";
        private string _indexTempFile = "./temp.ssn";
        private string _fileName = "./temp.txt";
        private int _index;
        private int _chapterIndex;
        private SortedList<int, string> _chapterList;
        private static string TEXT_READ = "朗读";
        private static string TEXT_STOP = "停止";

        public FrmMain()
        {
            InitializeComponent();
        }
        private string OpenFile()
        {
            using (var frm = new OpenFileDialog())
            {
                frm.Filter = "文本文档|*.txt";
                frm.Title = "选择 txt 文档的路径";
                if (frm.ShowDialog() == DialogResult.OK)
                {
                    return frm.FileName;
                }
                else
                {
                    return "";
                }
            }
        }
        #region 事件
        private void FrmMain_Load(object sender, EventArgs e)
        {
            if (!File.Exists(_indexTempFile))
            {
                File.Create(_indexTempFile).Close();
                File.WriteAllText(_indexTempFile, "0");
            }

            if (!File.Exists(_fileName))
            {
                string filepath = this.OpenFile();
                if (filepath.Length == 0)
                {
                    Environment.Exit(0);
                }
                File.Copy(filepath, _fileName, true);

            }

            _lines = this.ReadAllSentences(_fileName, FileEncoder.GetType(_fileName));
            this._chapterList = this.MakeChapterList(_lines);
            initForm();
        }
        const string REG_CHAPTER_STRING = "(第{0,1}[0-9一|二|三|四|五|六|七|八|九|十|百|千]*[集|回|章|节][ |　|、].+)\n(.+)";

        private SortedList<int, string> MakeChapterList(string[] lines)
        {
            // 加载目录
            SortedList<int, string> chapterList = new SortedList<int, string>();
            for (int i = 0; i < _lines.Length; i++)
            {
                string text = _lines[i];
                //text = text.Substring(0, text.Length - 1 > 100 ? 100 : text.Length - 1);
                //^(第[0-9一|二|三|四|五|六|七|八|九|十|百|千]*[集|回|章] .+)\n(.+)
                //text = "第1章 你好\n 张三说";
                char[] chapterChars = { '章', '节', '回', '集' };
                char[] numberChars = { '第' };
                int numberCharLoc = -1;
                int chapterCharLoc = -1;
                numberCharLoc = text.IndexOfAny(numberChars);
                chapterCharLoc = text.IndexOfAny(chapterChars);
                if ((numberCharLoc = text.IndexOfAny(numberChars)) != -1 &&
                    ((chapterCharLoc = text.IndexOfAny(chapterChars)) != -1) &&
                    (numberCharLoc < chapterCharLoc) &&
                    (numberCharLoc > chapterCharLoc - 6)
                 )
                {
                    var reg = new Regex(REG_CHAPTER_STRING);
                    var match = reg.Match(text);
                    if (match.Success)
                    {
                        string chapterName = match.Groups[1].Value;
                        chapterName = ShortenName(chapterName);
                        chapterList.Add(i, chapterName);
                    }
                }
            }
            return chapterList;
        }

        private string ShortenName(string text)
        {
            int maxChapterLength = 36;
            return text.Substring(0, text.Length - 1 > maxChapterLength ? maxChapterLength : text.Length - 1);
        }

        private string[] ReadAllSentences(string fileName, Encoding encoding)
        {
            List<string> sentences = new List<string>();
            string[] lines = File.ReadAllLines(_fileName, FileEncoder.GetType(_fileName));
            string txt = "";
            foreach (string line in lines)
            {
                if (line.Length == 0) continue;
                Char lastChar = line[line.Length - 1];
                if (lastChar == '。')
                {
                    txt += line;
                    sentences.Add(txt);
                    txt = "";
                }
                else
                {
                    txt += line + "\n";
                }
            }
            return sentences.ToArray();
        }

        private void FrmMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            //Stop("");
            Environment.Exit(0);
        }

        private void sddChapter_Click(object sender, EventArgs e)
        {
            // 打开目录窗口
            using (var frm = new FrmChapter(_chapterList, _chapterIndex))
            {

                if (frm.ShowDialog() == DialogResult.OK)
                {
                    initForm();
                }
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            PlayOrStop();
        }

        private void btnLast_Click(object sender, EventArgs e)
        {
            LastLine();
        }

        private void btnNext_Click(object sender, EventArgs e)
        {
            NextLine();
        }

        private void btnLastChapter_Click(object sender, EventArgs e)
        {
            LastChapter();
        }

        private void btnNextChapter_Click(object sender, EventArgs e)
        {
            NextChapter();
        }

        //protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        //{
        //    // 自定义快捷键
        //    KeyEventArgs e = new KeyEventArgs(keyData);

        //    // 空格键：朗读 / 停止
        //    if (keyData == (Keys.Space))
        //    {
        //        PlayOrStop();
        //    }

        //    // 右方向键：下一页
        //    if (keyData == (Keys.Right))
        //    {
        //        NextLine();
        //    }

        //    // 左方向键：上一页
        //    if (keyData == (Keys.Left))
        //    {
        //        LastLine();
        //    }

        //    // Control + 右方向键：下一章
        //    if (keyData == (Keys.Control | Keys.Right))
        //    {
        //        NextChapter();
        //    }

        //    // Control + 左方向键：上一章
        //    if (keyData == (Keys.Control | Keys.Left))
        //    {
        //        LastChapter();
        //    }
        //    return false;
        //}
        #endregion

        #region 方法
        /// <summary>
        /// 初始化窗口
        /// </summary>
        private void initForm()
        {
            statusStrip1.Focus();
            var temp = File.ReadAllLines(_indexTempFile)[0];
            _index = string.IsNullOrEmpty(temp) ? 0 : Convert.ToInt32(temp);

            txtText.Text = _lines[_index];

            if (_chapterList.Count > 0 && _chapterList.Keys[0] <= _index)
            {
                _chapterIndex = _index;
                while (!_chapterList.ContainsKey(_chapterIndex))
                {
                    _chapterIndex = _chapterIndex - 1;
                }
                Text = _lines[_chapterIndex];
            }

            tsProgress.Maximum = _lines.Length;
            tsProgress.Value = _index;
        }

        NovelReader novelReader = new NovelReader(3);
        private DateTime stopUtc;
        private int stopSeconds = FOR_EVER;

        private void SetSentenceInTxt(int index)
        {
            string text = _lines[index];
            if (string.IsNullOrEmpty(text) || text == "\0") return;

            // 使用正则表达式，抽取章节标题到标题栏
            var reg = new Regex(REG_CHAPTER_STRING);
            var match = reg.Match(text);
            if (match.Success)
            {
                _chapterIndex = index;
                Text = text;
            }

            txtText.Text = text;

            // 将中文转换为URL，格式为UTF-8
            //text = HttpUtility.UrlEncode(text, System.Text.Encoding.GetEncoding("UTF-8"));

            btnStart.Text = TEXT_STOP;
            sslStatus.Text = "";
        }

        /// <summary>
        /// 朗读
        /// </summary>
        /// <param name="index">当前行数</param>
        private void Read(int index)
        {
            novelReader.read(_lines, index);
            string text = _lines[index];
            if (string.IsNullOrEmpty(text) || text == "\0") return;

            // 使用正则表达式，抽取章节标题到标题栏
            var reg = new Regex(REG_CHAPTER_STRING);
            var match = reg.Match(text);
            if (match.Success)
            {
                _chapterIndex = index;
                Text = text;
            }

            txtText.Text = text;
            btnStart.Text = TEXT_STOP;
            sslStatus.Text = $"正在播放: {_index} / {_lines.Length}";
            tsProgress.Maximum = _lines.Length;
            tsProgress.Value = _index;
            novelReader.play(index);
            sslStatus.Text = "";
        }

        /// <summary>
        /// Http下载文件
        /// </summary>
        /// <param name="uri">下载地址</param>
        /// <param name="filefullpath">存放完整路径（含文件名）</param>
        /// <param name="size">每次多的大小</param>
        /// <returns>下载操作是否成功</returns>
        public static bool DownLoadFiles(string uri, string filefullpath, int size = 1024)
        {
            try
            {
                if (File.Exists(filefullpath))
                {
                    try
                    {
                        File.Delete(filefullpath);
                    }
                    catch (Exception)
                    {
                        return false;
                    }
                }
                string fileDirectory = System.IO.Path.GetDirectoryName(filefullpath);
                if (!Directory.Exists(fileDirectory))
                {
                    Directory.CreateDirectory(fileDirectory);
                }
                FileStream fs = new FileStream(filefullpath, FileMode.Create);
                byte[] buffer = new byte[size];
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
                request.Timeout = 10000;
                request.AddRange((int)fs.Length);

                Stream ns = request.GetResponse().GetResponseStream();

                long contentLength = request.GetResponse().ContentLength;

                int length = ns.Read(buffer, 0, buffer.Length);

                while (length > 0)
                {
                    fs.Write(buffer, 0, length);

                    buffer = new byte[size];

                    length = ns.Read(buffer, 0, buffer.Length);
                }
                fs.Close();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 延时 mm 毫秒
        /// </summary>
        /// <param name="mm">毫秒</param>
        public static void Delay(int mm)
        {
            DateTime current = DateTime.Now;
            while (current.AddMilliseconds(mm) > DateTime.Now)
            {
                Application.DoEvents();
            }
            return;
        }

        /// <summary>
        /// 朗读 / 停止
        /// </summary>
        private void PlayOrStop()
        {
            if (TEXT_STOP.Equals(btnStart.Text))
            {
                novelReader.stop();
                this.bntFindBefore.Enabled = true;
                this.bntFindAfter.Enabled = true;
                this.openFile.Enabled = true;
                this.playTime.Enabled = true;
                btnStart.Text = TEXT_READ;
            }
            else if (TEXT_READ.Equals(btnStart.Text))
            {
                this.bntFindBefore.Enabled = false;
                this.bntFindAfter.Enabled = false;
                this.openFile.Enabled = false;
                this.playTime.Enabled = false;
                if (this.stopSeconds != FOR_EVER)
                {
                    this.stopUtc = DateTime.Now.AddSeconds(this.stopSeconds);
                }
                _index--;
                do
                {
                    _index++;
                    if ((this.stopSeconds != FOR_EVER) && (this.stopUtc < DateTime.Now))
                    {
                        this.playTime.Text = "剩余0分";
                        btnStart.Text = TEXT_READ;
                    }
                    else if(this.stopSeconds == FOR_EVER)
                    {
                        btnStart.Text = TEXT_STOP;
                        this.playTime.Text = "一直播放";
                        Read(_index);
                        File.WriteAllText(_indexTempFile, Convert.ToString(_index));
                    } else if (this.stopUtc >= DateTime.Now)
                    {
                        this.playTime.Text = "剩余" + (int)this.stopUtc.Subtract(DateTime.Now).TotalMinutes + "分";
                        Read(_index);
                        File.WriteAllText(_indexTempFile, Convert.ToString(_index));
                    }
                }
                while (TEXT_STOP.Equals(btnStart.Text));
            }
        }

        /// <summary>
        /// 上一页 / 上一行
        /// </summary>
        private void LastLine()
        {
            if ((_index - 1) >= 0)
            {
                File.WriteAllText(_indexTempFile, Convert.ToString(--_index));
                initForm();
            }
            else
            {
                MessageBox.Show("当前已经是第一行，再没有啦！");
            }
        }

        /// <summary>
        /// 下一页 / 下一行
        /// </summary>
        private void NextLine()
        {
            if ((_index + 1) < _lines.Length)
            {
                File.WriteAllText(_indexTempFile, Convert.ToString(++_index));
                initForm();
            }
            else
            {
                MessageBox.Show("当前已经是最后一行，再没有啦！");
            }
        }

        /// <summary>
        /// 上一章
        /// </summary>
        private void LastChapter()
        {
            if (_chapterList.IndexOfKey(_chapterIndex) > 0)
            {
                _chapterIndex = _chapterList.Keys[_chapterList.IndexOfKey(_chapterIndex) - 1];
                File.WriteAllText(_indexTempFile, Convert.ToString(_chapterIndex));
                initForm();
            }
            else
            {
                MessageBox.Show("当前已经是第一章，再没有啦！");
            }
        }

        /// <summary>
        /// 下一章
        /// </summary>
        private void NextChapter()
        {
            if (_chapterList.IndexOfKey(_chapterIndex) < _chapterList.Count - 1)
            {
                _chapterIndex = _chapterList.Keys[_chapterList.IndexOfKey(_chapterIndex) + 1];
                File.WriteAllText(_indexTempFile, Convert.ToString(_chapterIndex));
                initForm();
            }
            else
            {
                MessageBox.Show("当前已经是最后一章，再没有啦！");
            }
        }

        #region sdk方式
        ///// <summary>
        ///// 合成
        ///// _ttsClient = new Baidu.Aip.Speech.Tts(API_KEY, SECRET_KEY);
        ///// </summary>
        //public void Tts()
        //{
        //    string text = "这个是第一个测试文本，让百度念给我听听，哈哈哈!";
        //    // 可选参数
        //    var option = new Dictionary<string, object>()
        //            {
        //                //{"tex",text},  // 合成的文本，使用UTF-8编码，请注意文本长度必须小于1024字节
        //                { "spd", 9}, // 语速，取值0-9，默认为5中语速
        //                //{ "pit", 5}, // 音调，取值0-9，默认为5中语调
        //                { "vol", 7}, // 音量，取值0-15，默认为5中音量
        //                { "per", 1}  // 发音人选择, 0为女声，1为男声，3为情感合成-度逍遥，4为情感合成-度丫丫，默认为普通女
        //            };
        //    var result = _ttsClient.Synthesis(text, option);

        //    if (result.ErrorCode == 0)  // 或 result.Success
        //    {
        //        File.WriteAllBytes("D://百度AI语音合成测试.mp3", result.Data);
        //    }
        //}
        #endregion

        #endregion

        private void statusStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void txtText_TextChanged(object sender, EventArgs e)
        {

        }

        private void label1_Click(object sender, EventArgs e)
        {

        }


        private void findBefore(string text, int fromIndex)
        {
            int index = fromIndex;
            for (int i = fromIndex - 1; i >= 0 && i < this._lines.Length; i--)
            {
                if (this._lines[i].Contains(text))
                {
                    this._index = i;
                    this.txtText.Text = this._lines[i];
                    tsProgress.Maximum = _lines.Length;
                    tsProgress.Value = _index;
                    return;
                }
            }
            Console.Beep(1000, 500);
        }
        private void findAfter(string text, int fromIndex)
        {
            int index = fromIndex;
            for (int i = fromIndex + 1; i >= 0 && i < this._lines.Length; i++)
            {
                if (this._lines[i].Contains(text))
                {
                    this._index = i;
                    this.txtText.Text = this._lines[i];
                    tsProgress.Maximum = _lines.Length;
                    tsProgress.Value = _index;
                    return;
                }
            }
            Console.Beep(1000, 500);
        }

        private void bntFindBefore_Click(object sender, EventArgs e)
        {
            this.findBefore(this.txtFind.Text, this._index);

        }

        private void bntFindAfter_Click(object sender, EventArgs e)
        {
            this.findAfter(this.txtFind.Text, this._index);

        }

        private void openFile_Click(object sender, EventArgs e)
        {
            string filepath = this.OpenFile();
            if (filepath.Length == 0)
            {
                return;
            }
            File.Copy(filepath, _fileName, true);
            _lines = this.ReadAllSentences(_fileName, FileEncoder.GetType(_fileName));
            this._chapterList = this.MakeChapterList(_lines);
            if (!File.Exists(_indexTempFile))
            {
                File.Create(_indexTempFile).Close();
                File.WriteAllText(_indexTempFile, "0");
            }
            else
            {
                File.WriteAllText(_indexTempFile, "0");
            }
            _index = 0;
            Read(_index);
        }
        const int FOR_EVER = 0;
        private void forever_Click(object sender, EventArgs e)
        {
            forever.Checked = true;
            s600.Checked = false;
            s1800.Checked = false;
            s3600.Checked = false;
            s7200.Checked = false;
            this.stopSeconds = FOR_EVER;
            this.playTime.Text = forever.Text;

        }

        private void s600_Click(object sender, EventArgs e)
        {
            forever.Checked = false;
            s600.Checked = true;
            s1800.Checked = false;
            s3600.Checked = false;
            s7200.Checked = false;
            this.stopSeconds = 600;
            this.playTime.Text = s600.Text;
        }

        private void s1800_Click(object sender, EventArgs e)
        {
            forever.Checked = false;
            s600.Checked = false;
            s1800.Checked = true;
            s3600.Checked = false;
            s7200.Checked = false;
            this.stopSeconds = 1800;
            this.playTime.Text = s1800.Text;
        }

        private void s3600_Click(object sender, EventArgs e)
        {
            forever.Checked = false;
            s600.Checked = false;
            s1800.Checked = false;
            s3600.Checked = true;
            s7200.Checked = false;
            this.stopSeconds = 3600;
            this.playTime.Text = s3600.Text;

        }

        private void s7200_Click(object sender, EventArgs e)
        {
            forever.Checked = false;
            s600.Checked = false;
            s1800.Checked = false;
            s3600.Checked = false;
            s7200.Checked = true;
            this.stopSeconds = 7200;
            this.playTime.Text = s7200.Text;
        }
    }
}
